﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nature.Toolkit;


namespace Nature.Toolkit.GMix
{
    /// <summary>
    /// MixExpression-specific extension of the CrossJoin class.
    /// </summary>
    /// <remarks>
    /// The MixCrossJoin extension automatically enlists one generic parameterized sequence consisting of a single NaN element.
    /// The enlistment does not change the total enumerations Count, but ensures that the enumeration consists of at least one item 
    /// (in the case when no other parameterized sequences are specified by the MixExpression)
    /// </remarks>
    class MixCrossJoin : CrossJoin<double, IRhsEnumerable>
    {
        #region Private Members

        const string GenericParameterName = "GenericParameter: 22e1c71a-c362-4d64-a03d-29f88ef0a8fd";

        private static List<IRhsEnumerable> EnlistGenericParameter(IEnumerable<IRhsEnumerable> rhsEnumerables)
        {
            List<IRhsEnumerable> list = new List<IRhsEnumerable>();
            list.AddRange(rhsEnumerables ?? Enumerable.Empty<IRhsEnumerable>());
            list.Add(new GenericParameter());
            return list;
        } 

        #endregion

        #region Nested Types
        class GenericParameter : IRhsEnumerable
        {
            #region IRhsEnumerable Members

            public string ParameterName
            {
                get { return MixCrossJoin.GenericParameterName; }
            }

            #endregion

            #region IEnumerable<double> Members

            public IEnumerator<double> GetEnumerator()
            {
                yield return double.NaN;
            }

            #endregion

            #region IEnumerable Members

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                yield return double.NaN;
            }

            #endregion
        } 
        #endregion

        internal MixCrossJoin() : this(Enumerable.Empty<IRhsEnumerable>()) { }

        internal MixCrossJoin(IEnumerable<IRhsEnumerable> rhsEnumerables) : base(MixCrossJoin.EnlistGenericParameter(rhsEnumerables)) { }
    }
}
